﻿

#include "zyAlphaLabel.h"

BlackMoonUI::zyAlphaLabel::zyAlphaLabel()
{
	SetMember(L"this", (LONG_PTR)this);
	SetMember(L"TextColor", (LONG_PTR)Gdiplus::Color::Blue);
	SetMember(L"TextAlign", 4);
	SetMember(L"Multiple", 0);
	SetMember(L"DirectionVertical", 0);
	m_obj->setWndProc(zyAlphaLabel_WndProc);
	m_obj->setDestroy(zyAlphaLabel_Destroy);
    setType(zyType_TransparentLabel);
}
BlackMoonUI::zyAlphaLabel::~zyAlphaLabel()
{

}
void BlackMoonUI::zyAlphaLabel::OnNCDestroy()
{

}
void WINAPI BlackMoonUI::zyAlphaLabel::zyAlphaLabel_Destroy(zyObject* obj)
{
	zyAlphaLabel* zyc = (zyAlphaLabel*)obj->getPtrData(L"this");
	zyc->OnNCDestroy();
	zyCustomCtrol::zyCustomCtrol_Destroy(obj);
}
LRESULT WINAPI BlackMoonUI::zyAlphaLabel::zyAlphaLabel_WndProc(zyObject* obj, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* bHandle)
{
	if (uMsg == WM_NCDESTROY) {
		zyAlphaLabel* zyc = (zyAlphaLabel*)obj->getPtrData(L"this");
		zyc->OnNCDestroy();
	}
	else if (uMsg == WM_PAINT) {
		PAINTSTRUCT ps;
		BeginPaint(hWnd, &ps);
		zyAlphaLabel* zyc = (zyAlphaLabel*)obj->getPtrData(L"this");
		zyc->zyTransparentTextView_OnPaint(hWnd,ps.hdc);
		*bHandle = true;
		EndPaint(hWnd, &ps);
		return 1;
	}
	else if (uMsg == WM_GETFONT) {
		*bHandle = true;
		return (LRESULT)obj->getPtrData(L"hFont");
	}
	else if (uMsg == WM_SETFONT) {
		obj->setPtrData(L"hFont", (void*)wParam);
		if (lParam != 0) {
			InvalidateRect(hWnd, 0, true);
		}
	}
	else if (uMsg == WM_ERASEBKGND) {
		if (obj->hasPtrData(L"pBackImage") == false && obj->hasPtrData(L"BackColor") == false) {
			*bHandle = true;
			return 1;
		}
	}
	return zyCustomCtrol::zyCustomCtrol_WndProc(obj, hWnd, uMsg, wParam, lParam, bHandle);
}
void BlackMoonUI::zyAlphaLabel::zyTransparentTextView_OnPaint(HWND hWnd, HDC hdc) {
    RECT rc = { 0 };
    GetClientRect(hWnd, &rc); // 获取窗口客户区大小

    // 创建离屏缓冲区
    zyBuffGraphics buff;
    if (!buff.Create(rc.right - rc.left, rc.bottom - rc.top, hdc)) {
        return; // 如果缓冲区创建失败，直接返回
    }

    // 获取父窗口坐标
    HWND hWndParent = GetParent(hWnd);
    POINT rcParent = { rc.left, rc.top };
    MapWindowPoints(hWnd, hWndParent, &rcParent, 1);

    // 绘制背景
    if (!HasMember(L"pBackImage") && !HasMember(L"BackColor")) {
        POINT oldPt = { 0 };
        SetViewportOrgEx(buff.gethdc(), -rcParent.x, -rcParent.y, &oldPt); // 调整视口原点
        SendMessage(hWndParent, WM_ERASEBKGND, (WPARAM)buff.gethdc(), 0); // 发送消息绘制父窗口背景
        SetViewportOrgEx(buff.gethdc(), oldPt.x, oldPt.y, &oldPt); // 恢复视口原点
    }
    else {
        OnDrawBack(hWnd, buff.gethdc()); // 如果有背景图片或背景颜色，调用自定义背景绘制函数
    }

    // 设置GDI+绘图对象
    Gdiplus::Graphics* g = buff.GetGraphics();
    g->SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); // 设置像素偏移模式
    g->SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); // 设置插值模式

    // 获取文本属性
    LONG_PTR TextColor = GetMember(L"TextColor"); // 文本颜色
    LONG_PTR align = GetMember(L"TextAlign"); // 文本对齐方式
    LONG_PTR Multiple = GetMember(L"Multiple"); // 是否多行文本
    LONG_PTR DirectionVertical = GetMember(L"DirectionVertical"); // 文本方向（垂直或水平）

    // 设置文本对齐方式
    Gdiplus::StringFormat stringFormat = Gdiplus::StringFormat::GenericTypographic();
    stringFormat.SetFormatFlags(0);
    SetTextAlignment(stringFormat, align); // 调用函数设置对齐方式

    // 设置文本方向
    if ((GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_RTLREADING) != 0) {
        stringFormat.SetFormatFlags(stringFormat.GetFormatFlags() | StringFormatFlagsDirectionRightToLeft); // 从右到左阅读
    }
    if (DirectionVertical != 0) {
        stringFormat.SetFormatFlags(stringFormat.GetFormatFlags() | StringFormatFlagsDirectionVertical); // 垂直文本
    }
    
    // 获取字体
    HFONT hFont = (HFONT)SendMessage(hWnd, WM_GETFONT, 0, 0); // 获取窗口字体
    std::unique_ptr<Gdiplus::Font> font;
    if (hFont) {
        font = std::make_unique<Gdiplus::Font>(hdc, hFont); // 使用窗口字体
    }
    else {
        font = std::make_unique<Gdiplus::Font>(hdc); // 使用默认字体
    }

    // 绘制文本
    int len = GetWindowTextLength(hWnd); // 获取文本长度
    if (len > 0) {
        std::wstring str(len + 1, L'\0'); // 创建字符串缓冲区
        GetWindowText(hWnd, &str[0], len + 1); // 获取窗口文本
        str.resize(len); // 调整字符串大小

        Gdiplus::RectF rcf(0, 0, (REAL)(rc.right - rc.left), (REAL)(rc.bottom - rc.top)); // 文本绘制区域
        Gdiplus::SolidBrush brush((Gdiplus::ARGB)TextColor); // 创建文本画刷
       
        if (Multiple == 0) {
            stringFormat.SetFormatFlags(stringFormat.GetFormatFlags() | StringFormatFlagsNoWrap); // 单行文本，不换行
            // 测量文本尺寸
            g->MeasureString(str.c_str(), -1, font.get(), rcf, &stringFormat, &rcf);
        }
        
        Gdiplus::Status lastResult = g->DrawString(str.c_str(), -1, font.get(), rcf, &stringFormat, &brush); // 绘制文本
        if (lastResult != Gdiplus::Ok) {
            return; // 如果绘制失败，直接返回
        }
    }
    // 将离屏缓冲区内容复制到屏幕
    buff.Copy2dc(hdc, 0, 0, rc.right - rc.left, rc.bottom - rc.top, 0, 0, SRCCOPY);
   // buff.Destory();
}

// 设置文本对齐方式的辅助函数
void BlackMoonUI::zyAlphaLabel::SetTextAlignment(Gdiplus::StringFormat& stringFormat, LONG_PTR align) {
    switch (align) {
    case 7: stringFormat.SetAlignment(StringAlignmentNear); stringFormat.SetLineAlignment(StringAlignmentNear); break; // 左对齐
    case 8: stringFormat.SetAlignment(StringAlignmentCenter); stringFormat.SetLineAlignment(StringAlignmentNear); break; // 水平居中，顶部对齐
    case 9: stringFormat.SetAlignment(StringAlignmentFar); stringFormat.SetLineAlignment(StringAlignmentNear); break; // 右对齐
    case 4: stringFormat.SetAlignment(StringAlignmentNear); stringFormat.SetLineAlignment(StringAlignmentCenter); break; // 左对齐，垂直居中
    case 5: stringFormat.SetAlignment(StringAlignmentCenter); stringFormat.SetLineAlignment(StringAlignmentCenter); break; // 水平和垂直居中
    case 6: stringFormat.SetAlignment(StringAlignmentFar); stringFormat.SetLineAlignment(StringAlignmentCenter); break; // 右对齐，垂直居中
    case 1: stringFormat.SetAlignment(StringAlignmentNear); stringFormat.SetLineAlignment(StringAlignmentFar); break; // 左对齐，底部对齐
    case 2: stringFormat.SetAlignment(StringAlignmentCenter); stringFormat.SetLineAlignment(StringAlignmentFar); break; // 水平居中，底部对齐
    case 3: stringFormat.SetAlignment(StringAlignmentFar); stringFormat.SetLineAlignment(StringAlignmentFar); break; // 右对齐，底部对齐
    default: stringFormat.SetAlignment(StringAlignmentNear); stringFormat.SetLineAlignment(StringAlignmentNear); break; // 默认左对齐
    }
}
BOOL BlackMoonUI::zyAlphaLabel::创建(HWND 参数_父窗口, const std::wstring& 参数_标题, POINT 参数_位置, POINT 参数_尺寸, int 参数_ID, int 参数_窗口风格, int 参数_扩展风格)
{
	MyRegisterClass(zyEnv::getInstance().getHandle(), L"zyAlphaLabel", 0, 0);

	if (参数_ID == NULL)
		参数_ID = 黑月默认ID();

	return _CreateWindow(参数_父窗口, 参数_标题, 参数_位置, 参数_尺寸, 参数_ID, 参数_窗口风格 , 参数_扩展风格, L"zyAlphaLabel");
}

BOOL BlackMoonUI::zyAlphaLabel::创建(zyWindow& 参数_父窗口, const std::wstring& 参数_标题, POINT 参数_位置, POINT 参数_尺寸, int 参数_ID, int 参数_窗口风格, int 参数_扩展风格)
{
	MyRegisterClass(zyEnv::getInstance().getHandle(), L"zyAlphaLabel", 0, 0);
	if (参数_ID == NULL)
		参数_ID = 黑月默认ID();

	return _CreateWindow(参数_父窗口.getHwnd(), 参数_标题, 参数_位置, 参数_尺寸, 参数_ID, 参数_窗口风格 , 参数_扩展风格, L"zyAlphaLabel");

}
COLORREF BlackMoonUI::zyAlphaLabel::文本色(COLORREF 参数_文本色)
{
    if (参数_文本色 == 0) {
        return (COLORREF)GetMember(L"TextColor");
    }
    else {
        SetMember(L"TextColor", 参数_文本色);
        重画();
        return 参数_文本色;
    }
}
int BlackMoonUI::zyAlphaLabel::对齐方式(int 参数_对齐方式)
{
    if (参数_对齐方式 == -1) {
        return (int)GetMember(L"TextAlign");
    }
    else {
        SetMember(L"TextAlign", 参数_对齐方式);
        重画();
        return 参数_对齐方式;
    }
}
bool BlackMoonUI::zyAlphaLabel::自动换行(bool 参数_自动换行)
{
    SetMember(L"Multiple", 参数_自动换行);
    重画();
    return 参数_自动换行;
}
bool BlackMoonUI::zyAlphaLabel::自动换行()
{
    return GetMember(L"Multiple");
}
bool BlackMoonUI::zyAlphaLabel::垂直显示(bool 参数_垂直显示)
{
    SetMember(L"DirectionVertical", 参数_垂直显示);
    重画();
    return 参数_垂直显示;
}
bool BlackMoonUI::zyAlphaLabel::垂直显示()
{
    return GetMember(L"DirectionVertical");
}